package xorm

import (
	"gitee.com/stevenchin/gin_study/xorm/initxorm"
	"github.com/gin-gonic/gin"
	"github.com/xormplus/xorm"
	"net/http"
)

/*
xorm支持主从数据库(Master/Slave)数据库读写分离。
*/
var conn = []string{
	"d_mymro_oms_admin:n6sdTiwfj1rqBC3h@tcp(759b8d27dbc147789e0f79c7b098c0e3in01.internal.cn-east-3.mysql.rds.myhuaweicloud.com:3306)/d_mymro_oms?charset=utf8&sslmode=disable;",
	"d_mymro_oms_admin:n6sdTiwfj1rqBC3h@tcp(759b8d27dbc147789e0f79c7b098c0e3in01.internal.cn-east-3.mysql.rds.myhuaweicloud.com:3306)/d_mymro_oms?charset=utf8&sslmode=disable;",
	"d_mymro_oms_admin:n6sdTiwfj1rqBC3h@tcp(759b8d27dbc147789e0f79c7b098c0e3in01.internal.cn-east-3.mysql.rds.myhuaweicloud.com:3306)/d_mymro_oms?charset=utf8&sslmode=disable;",
}

//一. 创建引擎组。见orm1.go 的CreteEngineGroup() 方法

//二. 负载策略。
// 通过xorm.NewEngineGroup创建EngineGroup时，第三个参数为policies，我们可以通过该参数来指定Slave访问的负载策略。如创建
// EngineGroup时未指定，则默认使用轮询的负载策略。xorm中内置五种负载策略，分别为随机访问负载策略，权重随机访问负载策略，
// 轮询访问负载策略，权重轮询访问负载策略和最小连接数访问负载策略。开发者也可以通过实现GroupPolicy接口，来实现自定义负载策略

func policy() {

	// 1. 随机访问负载策略
	_, _ = xorm.NewEngineGroup(xorm.MYSQL_DRIVER, conn, xorm.RandomPolicy())

	// 2. 权重随机访问负载策略。此时设置的golang_db1数据库和golang_db2数据库的随机访问权重为2和3
	_, _ = xorm.NewEngineGroup(xorm.MYSQL_DRIVER, conn, xorm.WeightRandomPolicy([]int{2, 3}))

	// 3. 轮询访问负载策略
	_, _ = xorm.NewEngineGroup(xorm.MYSQL_DRIVER, conn, xorm.RoundRobinPolicy())

	// 4. 权重轮询访问负载策略。此时设置的golang_db1数据库和golang_db2数据库的轮询访问权重为2和3
	_, _ = xorm.NewEngineGroup(xorm.MYSQL_DRIVER, conn, xorm.WeightRoundRobinPolicy([]int{2, 3}))

	// 5. 最小连接数访问负载策略
	_, _ = xorm.NewEngineGroup(xorm.MYSQL_DRIVER, conn, xorm.LeastConnPolicy())

	// 6. 自定义负载策略
}

//三. 数据库读写分离（TIPS：貌似不行，只能插入主数据库中，不知道是不是项目里实例化了两个引擎的原因）
// 	  EngineGroup对数据库的SQL操作方法集和Engine是完全一致的，上例中则是对数据库进行Insert操作，写操作和数据库事务操作都将
// 	  在Master数据库中执行。而读操作则是依据负载策略在某个Slave中执行
func EngineGroup(ctx *gin.Context) {

	param := ctx.Param("select")
	if param == "insert" {
		basic := new(basic)
		basic.Name = "读写分离测试"
		basic.Password = "thisPassword"
		basic.Age = 10
		if i, err := initxorm.GroupEngine.Insert(basic); err != nil {
			ctx.String(http.StatusInternalServerError, err.Error())
		} else {
			ctx.JSON(http.StatusOK, gin.H{"id": basic.Id, "affected": i})
		}
	} else if param == "select" {
		basics := make([]*basic, 0) // 创建slice时初始化大小为0，这样避免初始值的问题
		_ = initxorm.GroupEngine.Find(&basics)
		ctx.JSON(http.StatusOK, basics)
	} else {
		ctx.String(http.StatusBadRequest, "没有匹配的处理逻辑")
	}
}

//四. EngineGroup的Session
// 	  EngineGroup和Engine一样可以通过NewSession()方法来创建EngineGroup的Session。xorm并不推荐在同一个EngineGroup的Session中同时
// 	  进行读写操作，如需要，请使用事务，事务操作将全部在Master数据库中执行读写操作
